AndroidX RecyclerView总结

您所在的位置:网站首页 recyclerview嵌套recyclerview 滑动 AndroidX RecyclerView总结

AndroidX RecyclerView总结

2024-06-26 08:44:57| 来源: 网络整理| 查看: 265

文章目录 概述 源码探究 RecyclerView中的处理 onInterceptTouchEvent 滑动状态 onTouchEvent scrollStep LinearLayoutManager中的处理 updateLayoutState fill offsetChildren 总结

概述

RecyclerView作为一个灵活的在有限窗口显示大量数据集的视图组件,继承自ViewGroup,需要处理触摸事件产生时子View的滚动。同时RecyclerView实现了NestedScrollingChild接口,也支持嵌套在支持Nested的父容器中。

这里结合LinearLayoutManager,以垂直方向滑动为例,从源码浅析RecyclerView是如何进行滑动事件处理的。

源码探究

文中源码基于 ‘androidx.recyclerview:recyclerview:1.1.0’

RecyclerView中的处理

RecyclerView和常规事件处理方式一样,重写了onInterceptTouchEvent和onTouchEvent。RecyclerView也实现了NestedScrollingChild接口,在关键事件节点也会通知实现了NestedScrollingParent接口的父容器。

关于NestedScrollingChild和NestedScrollingParent的简要用法和说明,可参考《关于NestedScrollingParent2、NestedScrollingChild2接口》

onInterceptTouchEvent

[RecyclerView#onInterceptTouchEvent]

public boolean onInterceptTouchEvent(MotionEvent e) { // 判断是否抑制布局滚动,可通过suppressLayout方法设置为true,当重新设置Adapter或托管item动画时不拦截。 if (mLayoutSuppressed) { // When layout is suppressed, RV does not intercept the motion event. // A child view e.g. a button may still get the click. return false; } // 省略OnItemTouchListener部分,设置FastScroller或ItemTouchHelper时涉及 ··· if (mLayout == null) { return false; } // 获取支持滚动的方向。以垂直排列的LinearLayoutManager为例,canScrollVertically为true。 final boolean canScrollHorizontally = mLayout.canScrollHorizontally(); final boolean canScrollVertically = mLayout.canScrollVertically(); if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(e); final int action = e.getActionMasked(); final int actionIndex = e.getActionIndex(); switch (action) { case MotionEvent.ACTION_DOWN: // mIgnoreMotionEventTillDown默认为false,调用suppressLayout抑制布局滚动时会将其置为true if (mIgnoreMotionEventTillDown) { mIgnoreMotionEventTillDown = false; } // 获取第一个触摸点的ID mScrollPointerId = e.getPointerId(0); // 保存DOWN时X、Y坐标,用于计算滑动偏移量 mInitialTouchX = mLastTouchX = (int) (e.getX() + 0.5f); mInitialTouchY = mLastTouchY = (int) (e.getY() + 0.5f); // 判断当前滑动状态是否是惯性滑动或其他非用户触摸滑动,mScrollState默认为SCROLL_STATE_IDLE if (mScrollState == SCROLL_STATE_SETTLING) { // 请求父布局不拦截事件 getParent().requestDisallowInterceptTouchEvent(true); // 更新滑动状态为SCROLL_STATE_DRAGGING setScrollState(SCROLL_STATE_DRAGGING); // 通知父布局停止滑动,类型为TYPE_NON_TOUCH stopNestedScroll(TYPE_NON_TOUCH); } // Clear the nested offsets mNestedOffsets[0] = mNestedOffsets[1] = 0; // 获取当前支持的滑动方向 int nestedScrollAxis = ViewCompat.SCROLL_AXIS_NONE; if (canScrollHorizontally) { nestedScrollAxis |= ViewCompat.SCROLL_AXIS_HORIZONTAL; } if (canScrollVertically) { nestedScrollAxis |= ViewCompat.SCROLL_AXIS_VERTICAL; } // 通知父布局滑动即将开始 startNestedScroll(nestedScrollAxis, TYPE_TOUCH); break; case MotionEvent.ACTION_POINTER_DOWN: // 有新的触摸点,更新触摸点ID和初始X、Y坐标以新的为准 mScrollPointerId = e.getPointerId(actionIndex); mInitialTouchX = mLastTouchX = (int) (e.getX(actionIndex) + 0.5f); mInitialTouchY = mLastTouchY = (int) (e.getY(actionIndex) + 0.5f); break; case MotionEvent.ACTION_MOVE: { final int index = e.findPointerIndex(mScrollPointerId); if (index // 计算滑动偏移量 final int dx = x - mInitialTouchX; final int dy = y - mInitialTouchY; // 标记是否有任一方向可以滑动 boolean startScroll = false; // 判断是否构成滑动,mTouchSlop为最小滑动距离 if (canScrollHorizontally && Math.abs(dx) > mTouchSlop) { // 保存刚开始滑动时的坐标 mLastTouchX = x; startScroll =


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭